package niconama04.model.impl;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import javax.jdo.PersistenceManager;

import niconama04.model.Loader;
import niconama04.model.RandomLoader;
import niconama04.model.Transacter;


public class TransacterFactory {

	/** インスタンス */
	private static final TransacterFactory instance = new TransacterFactory();

	private final Loader loader = (Loader) Proxy.newProxyInstance(Loader.class.getClassLoader(), new Class[]{Loader.class}, new InvocationHandler() {

		@Override
		public Object invoke(Object x_proxy, Method x_method, Object[] x_args) throws Throwable {
			Object result = null;
			PersistenceManager pm = PMF.get().getPersistenceManager();
			try {
				Dao dao = new Dao(pm);
				Loader obj = new LoaderImpl(dao);
				result = x_method.invoke(obj, x_args);
			} finally {
				pm.close();
			}
			return result;
		}
	});

	private final RandomLoader randomLoader = (RandomLoader) Proxy.newProxyInstance(RandomLoader.class.getClassLoader(), new Class[]{RandomLoader.class}, new InvocationHandler() {

		@Override
		public Object invoke(Object x_proxy, Method x_method, Object[] x_args) throws Throwable {
			Object result = null;
			PersistenceManager pm = PMF.get().getPersistenceManager();
			try {
				Dao dao = new Dao(pm);
				RandomLoader obj = new RandomLoaderImpl(dao);
				result = x_method.invoke(obj, x_args);
			} finally {
				pm.close();
			}
			return result;
		}
	});

	private final Transacter transacter = (Transacter) Proxy.newProxyInstance(Transacter.class.getClassLoader(), new Class[]{Transacter.class}, new InvocationHandler() {

		@Override
		public Object invoke(Object x_proxy, Method x_method, Object[] x_args) throws Throwable {
			Object result = null;
			PersistenceManager pm = PMF.get().getPersistenceManager();
			try {
				Dao dao = new Dao(pm);
				Transacter obj = new TransacterImpl(dao);
				result = x_method.invoke(obj, x_args);
			} finally {
				pm.close();
			}
			return result;
		}
	});

	/**
	 * [constructor]
	 */
	private TransacterFactory() {
	}

	/**
	 * インスタンスを返す
	 *
	 * @return インスタンス
	 */
	public static TransacterFactory getInstance() {
		return instance;
	}

	public Loader getLoader() {
		return loader;
	}

	public RandomLoader getRandomLoader() {
		return randomLoader;
	}

	public Transacter getTransacter() {
		return transacter;
	}
}
